CSAW ncore Write Up
Details:
Jeopardy style CTF
Category: Reverse Engineering
Comments:
We have a very safe core with a very safe enclave.
nc rev.chal.csaw.io 5002
Write up:
The server.py file was not too important for this challenge as it only really set up the verilog.
The most important parts of the verilog were:
The opcodes and their values:
`define ADD 4'd0
`define SUB 4'd1
`define AND 4'd2
`define OR 4'd3
`define RES 4'd4
`define MOVF 4'd5
`define MOVT 4'd6
`define ENT 4'd7
`define EXT 4'd8
`define JGT 4'd9
`define JEQ 4'd10
`define JMP 4'd11
`define INC 4'd12
`define MOVFS 4'd13
How the flag was getting loaded into memory:
task load_safeROM();
$display("loading safe rom, safely...");
$readmemh("flag.hex",safe_rom);
endtask
The key generation:
task set_key();
int tmp;
// key[0] = 0;
read_file_descriptor=$fopen("/dev/urandom","rb");
tmp = $fread(key, read_file_descriptor);
$readmemh("/dev/urandom",key);
endtask
What was printed at the end of the program:
task print_res();
integer i;
for( i=0; i<64; i = i + 1) begin
$write("%h ",ram[255-i]);
end
$write("\n");
endtask
The opcode that moved memory from the flag.hex file into memory we can print:
`MOVFS: begin
if(emode) begin
regfile[ram[pc][5:4]] <= safe_rom[ram[pc+1]];
end
increment_pc();
And the condition and opcode we needed to meet in order for us to be able to call the previous opcode:
`ENT: begin
// $display("%d | %d",regfile[0],key[0][13:0]);
if(key[0][13:0]==regfile[0]) begin
emode <= 1;
regfile[3] <= 0;
$display("ENT");
end else begin
regfile[3] <= 1;
end
increment_pc();
Based on this information we saw that we would need to do the following:
ENT
INC [0]
ENT
JGT [3] 0
MOVFS
We first call ENT in order to set regfile[3] to 1. We then increment regfile[0] since that is what is compared to the key. We then run ENT again to check if we got the key. Then we run JGT to see if regfile[3] is still 1 or 0, if it is 1 we return back to the INC, otherwise we move the safe_rom data to the ram.
The code for the first part of this was:
07 00 0c 00 07 00 79 02
We then had to add some padding to our "code" since we didn't want to write the flag to the last 64 bytes for them to then be parsed and thus changing the output. So we put 184 ff's so that our final move code would be in the last 64 printable bytes.
Since we only had 64 printable bytes we could only display 16 flag characters per connection since the code for each character would be:
0d [index of character in flag] 06 [ram position to write to]
I then wrote the following solve script:
from pwn import *
flag = []
# connect twice since the flag is 32 long
for i in range(2):
# connect to the server
r = remote('rev.chal.csaw.io', 5002)
# receive the welcome line
r.recvline()
# initialize the string
exploit = ''
# loop through 16 times to write the exploit
for j in range(16):
# get the character index in the flag
count = str(hex(j + (i * 16)))[2:]
# if the hex is small (< 0x10) we need to prepend 0
if len(count) == 1:
count = '0'+ count
# add the code to the exploit
exploit += '0d ' + count + ' 06 ' + str(hex(0xc0 + j))[2:] + ' '
# send the "code" we generate
r.sendline('07 00 0c 00 07 00 79 02 ' + ('ff ' * 184) + exploit)
# receive the data we just sent
r.recvline()
# get the output
output = r.recvline()
# get rid of the parts we don't care about
output = str(output[output.find(b'\\nENT\\n') + 7:])[2:-8]
# append the 16 bytes (and spaces between them) we care about to flag
flag.append(output[-47:])
# intialize our output string
s = ""
# loop through all flag components
for i in flag:
# intialize current string
cur = ""
# loop through the current component, increment by 3 (2 byte characters and space)
for j in range(0, len(i), 3):
# if the character isn't an x (this was from when we overshot the flag)
if i[j] != 'x':
# turn the byte into a character
cur += chr(int(i[j]+i[j+1], 16))
# append the current string in reverse order to the string
s += cur[::-1]
# print the flag
print(s)
When run I got:
[+] Opening connection to rev.chal.csaw.io on port 5002: Done
[+] Opening connection to rev.chal.csaw.io on port 5002: Done
flag{d0nT_mESs_wiTh_tHe_sChLAmi}